package com.iwhalecloud.bss.kite.cucc.service.scene;

import com.alibaba.fastjson.JSON;
import com.iwhalecloud.bss.kite.cart.client.api.cart.operate.IOperateKiteCartService;
import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteShoppingCartService;
import com.iwhalecloud.bss.kite.cart.client.dto.req.KiteCartCommitRequestDTO;
import com.iwhalecloud.bss.kite.client.api.ord.IChangeServiceLogService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.order.ChangeServiceLogDTO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.client.api.cust.ILatestCustomerService;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.inf.IInfServiceBus;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ISceneCommitService;
import com.iwhalecloud.bss.kite.cucc.client.api.shoppingcart.operate.ICuccOperateShoppingCartService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.inf.InfServContextDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalDcPublicConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalInfConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ExtOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ResaleOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.route.InfServParamUtils;
import com.iwhalecloud.bss.kite.cucc.service.route.InfServRouteFactory;
import com.iwhalecloud.bss.kite.cucc.service.route.enums.InfServRouteEnum;
import com.iwhalecloud.bss.kite.cucc.service.util.KiteDcPublicUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.service.context.ServiceContext;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Service
public class SceneCommitService implements ISceneCommitService {

    private final ZLogger logger = ZLoggerFactory.getLogger(SceneCommitService.class, KeyConsts.LOG_MODULE);

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private ICuccOperateShoppingCartService cuccOperateShoppingCartService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private IInfServiceBus infServiceBus;

    @Autowired
    private ILatestCustomerService latestCustomerService;

    @Override
    public DataResult<String> commitScene(String sceneInstId, String staffId, String orgId, CuccContextCustDTO custDto, Boolean checkAccountModule, Boolean checkContractModule) {
        // 下单服务
        return commit(sceneInstId, staffId, orgId, custDto, checkAccountModule, checkContractModule, null);
    }

    @Override
    public DataResult<String> batchAcceptCommit(String sceneInstId, String staffId, String orgId,
        CuccContextCustDTO custDto, String curOfferInstId) {
        // 下单服务
        return commit(sceneInstId, staffId, orgId, custDto, null, null, curOfferInstId);
    }

    private DataResult<String> commit(String sceneInstId, String staffId, String orgId, CuccContextCustDTO custDto,
        Boolean checkAccountModule, Boolean checkContractModule, String curOfferInstId) {
        InfServContextDTO context = InfServParamUtils.genSceneCommit(sceneInstId, staffId, orgId, custDto,
            checkAccountModule, checkContractModule, curOfferInstId);
        Map<String, Object> respMap = InfServRouteFactory.getInstance(InfServRouteEnum.SCENE_COMMIT_ROUTE)
            .commitScene(context);

        Map<String, Object> headMap = (Map<String, Object>) respMap.get("UNI_BSS_HEAD");
        if (!KiteStringUtils.equals(KiteMapUtils.getString(headMap, "RESP_CODE"), LocalInfConsts.RESP_SUCCESS)) {
            return ErrorConsts.BUSI_COMMON_ERROR.getResult(KiteMapUtils.getString(headMap, "RESP_DESC"));
        }

        Map<String, Object> bodyMap = (Map<String, Object>) respMap.get("UNI_BSS_BODY");
        Map<String, Object> dataMap = (Map<String, Object>) bodyMap.get("PATH_VARIABLE_RSP");

        StringBuilder result = new StringBuilder();
        if (KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(dataMap, "STATUS"))) {

            String rootInstId = this.querySceneInstService.getSceneInst(sceneInstId).getRootInstId();
            InstType instType = this.querySceneInstService.getSceneInst(sceneInstId).getRootInstType();
            KiteInst kiteInst = this.querySceneInstService.getKiteInst(custDto.getCustId(), instType, rootInstId);
            String cateId = OfferCache.get(kiteInst.getSpecId()).getCateId();
            String extTips = DcPublicCache.getCodea("20201218001", cateId);
            String lanId = ContextUtil.getLandId();
            String postId = ContextUtil.getSimpleLoginInfo().getPostId() + "";
            if (!KiteDcPublicUtils.isCollectionGroup(sceneInstId)) {
                //保存最近受理商品和客户
//                CompletableFuture.runAsync(() -> {
//                    goodsService.operateLatestAcceptGoods(staffId, orgId, postId, sceneInstId);
//                    latestCustomerService.dealLatestCustomer(staffId, orgId, lanId, custDto);
//                });
                TransactionUtils.executeNew(() -> {
                    goodsService.operateLatestAcceptGoods(staffId, orgId, postId, sceneInstId);
                    latestCustomerService.dealLatestCustomer(staffId, orgId, lanId, custDto);
                });
            }

            if (!CuccPosServiceUtils.isBatchAccept(sceneInstId)) {
                archiveData(sceneInstId, staffId, orgId, custDto.getCustId());
            }
            // 返销生成订单时删除缓存的订单详情数据
            ResaleOrderInfoCache.getInst().defaultDelete(querySceneInstService.getExtParameterValue(sceneInstId, "RESALE_ORDER_ID"));
            ExtOrderInfoCache.getInst().defaultDelete(sceneInstId);
            result.append(KiteMapUtils.getString(dataMap, "DATA"));
            DataResult<String> dataResult = ErrorConsts.SUCCESS.getResult(result.toString());
            if (!KiteStringUtils.isEmpty(extTips)) {
                dataResult.setResultMsg(extTips);
            }
            // 变更业务的场景初始化过程中不校验
            KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
            String serviceOfferId = sceneInst.getServiceOfferId();
            if (!ServiceOfferConsts.SERVICE_OFFER_ORDER.equals(serviceOfferId)
                && KeyConsts.IFTRUE_T.equals(querySceneInstService.getExtParameterValue(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE))) {
                // 写产品变更服务操作日志
                String instId = querySceneInstService.getExtParameterValue(sceneInstId, "instanceId");
                String accNum = querySceneInstService.getExtParameterValue(sceneInstId, "business_number");
                ChangeServiceLogDTO logDto = new ChangeServiceLogDTO();
                logDto.setLogId(SeqUtils.getNext("SEQ_KITE_CHANGE_SERVICE_LOG_LOG_ID"));
                logDto.setCustId(custDto.getCustId());
                logDto.setInstId(instId);
                logDto.setAccNum(accNum);
                logDto.setServiceOfferId(serviceOfferId);
                logDto.setReqTime(KiteDateUtils.dateToLocalDateTime(new Date()));
                logDto.setOperStaff(staffId);
                IChangeServiceLogService service = SpringUtil.getBean(IChangeServiceLogService.class);
                service.addKiteServiceLog(logDto);
            }
            return dataResult;
        }
        else {
            result.append(KiteMapUtils.getString(dataMap, "MESSAGE"));
            return ErrorConsts.BUSI_COMMON_ERROR.getResult(result.toString());
        }
    }

    @Override
    public void archiveData(String sceneInstId, String staffId, String orgId, String custId) {
        CompletableFuture.runAsync(() -> {
            String cartId = querySceneInstService.getSceneInst(sceneInstId).getCartId();
            if (KiteStringUtils.isEmpty(cartId)) {
                IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                    .getBean(IQueryKiteShoppingCartService.class);
                // 获取分片键 cartId
                Long cartIdd = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId.toString()).getResultObject();
                if (cartIdd != null) {
                    cartId = KiteStringUtils.valueOf(cartIdd);
                }
            }

            KiteCartCommitRequestDTO request = new KiteCartCommitRequestDTO();
            request.setCartId(cartId);
            request.setGroupIds(Collections.singletonList(sceneInstId));

            IOperateKiteCartService operateKiteCartService = SpringUtil.getBean(IOperateKiteCartService.class);
            operateKiteCartService.commitKiteCart(request);
            cuccOperateShoppingCartService.archiveOrdInsts(sceneInstId, staffId, orgId, custId, request.getCartId());
            operateSceneInstService.deleteSceneInst(sceneInstId, custId);
        });
    }

    @Override
    public DataResult<String> commitModifyScene(String sceneInstId, String sysUserId, String orgId, CuccContextCustDTO custDto, KitePosDTO posDto) {
        this.checkWlwRealName(sceneInstId, custDto);
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        String orderId = querySceneInstService.getExtParameterValue(sceneInstId, "orderId");
        Map<String, Object> respMap = infServiceBus.orderCenterUpdatePiece(posDto, custDto.getCustId(), orderId);

        Map<String, Object> uniBssHead = KiteMapUtils.getValue(respMap, "UNI_BSS_HEAD");
        if (!KiteStringUtils.equals(KiteMapUtils.getString(uniBssHead, "RESP_CODE"), LocalInfConsts.RESP_SUCCESS)) {
            ErrorConsts.INF_INVOKE_EXCEPTION.throwOut(KiteMapUtils.getString(uniBssHead, "RESP_DESC"));
        }
        Map<String, Object> uniBssBody = KiteMapUtils.getValue(respMap, "UNI_BSS_BODY");
        Map<String, Object> updatePieceRsp = KiteMapUtils.getValue(uniBssBody, "UPDATE_PIECE_RSP");
        if (!KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(updatePieceRsp, "status"))) {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(updatePieceRsp, "status"), KiteMapUtils.getString(updatePieceRsp, "message"));
        }
        return ErrorConsts.SUCCESS.getResult("订单修改成功");
    }

    @Override
    public void checkWlwRealName(String sceneInstId, CuccContextCustDTO custDto) {
        // 批量处理不进行实名校验
        if (ServiceContext.getIsBatchAccept()) {
            return;
        }
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        String offerInstId = querySceneInstService.getSceneInst(sceneInstId).getRootInstId();
        logger.info(String.format("checkWlwRealName ==> sceneInstId:%s,CuccContextCustDTO:%s,offerInstId:%s", sceneInstId, JSON.toJSONString(custDto), offerInstId));
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custDto.getCustId(), offerInstId);
        logger.info(String.format("checkWlwRealName ==> offerInst:%s", JSON.toJSONString(offerInst)));
        String offerId = offerInst.getSpecId();
        String cateId = OfferCache.get(offerId).getCateId();
        cateId = DcPublicCache.getPCode(LocalDcPublicConsts.DC_20201208002, cateId);
        if (!KiteStringUtils.isEmpty(cateId)) {
            // 需要进行物联网实名校验的产品分类
            Map<String, Object> outParams = infServiceBus.queryCustIOTInfos(custDto.getCustId(), custDto.getProvinceCode(), 1, 1);
            if (outParams != null) {
                outParams = (Map<String, Object>) outParams.get("UNI_BSS_BODY");
                outParams = (Map<String, Object>) outParams.get("QRY_CUST_IOT_INFO_LIST_RSP");
                if (outParams == null) {
                    ErrorConsts.BUSI_COMMON_ERROR.throwOut("查询不到物联网实名信息，不能修改订单");
                }
                List<Map<String, Object>> dataList = (List<Map<String, Object>>) outParams.get("DATA_LIST");
                if (!KiteListUtils.isEmpty(dataList)) {
                    Map<String, Object> data = dataList.get(0);
                    if (!KiteStringUtils.equals((String) data.get("IS_REAL"), "1")) {
                        ErrorConsts.BUSI_COMMON_ERROR.throwOut("客户未进行物联网实名，不能修改订单");
                    }
                }
            }
        }
    }
}
